package com.distribute.framework.core.web.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;


@SuppressWarnings("unchecked")
public class Tree
{	
	public static final Integer ORDER_COAT=0;//层形
	public static final Integer ORDER_TREE=1;//树形	
	
	public static List OrderList(List list,String primaryKey,String treeKey,Integer type){	
		List treeList=new ArrayList();		
		if(type.intValue()==ORDER_TREE.intValue()){
			
			Map treeMap=new HashMap();
			{
				Map objectMap=new HashMap();			
				for(Object object:list)
					objectMap.put(getObjectKeyValue(object,primaryKey), object);
				for(Object object:list){
					Object treeKeyValue=getObjectKeyValue(object,treeKey);
					Object primaryKeyValue=getObjectKeyValue(object,primaryKey);
					if(objectMap.get(treeKeyValue)==null)
					{
						treeMap.put(primaryKeyValue, object);
						treeList.add(object);
					}
				}
			}
			
			while(true){
				List haveParentList=new ArrayList();
				for(Object object:list){
					Object treeKeyValue=getObjectKeyValue(object,treeKey);
					if(treeMap.get(treeKeyValue)!=null)
						haveParentList.add(object);
				}
				if(haveParentList.isEmpty())
					break;
				
				treeMap.clear();
				for(Object object:haveParentList){
					Object primaryKeyValue=getObjectKeyValue(object,primaryKey);					
					treeMap.put(primaryKeyValue, object);
					treeList.add(object);
				}
			}
		}
		else if(type.intValue()==ORDER_COAT.intValue()){
			
			{
				Map objectMap=new HashMap();			
				for(Object object:list)
					objectMap.put(getObjectKeyValue(object,primaryKey), object);			
				for(Object object:list){
					Object treeKeyValue=getObjectKeyValue(object,treeKey);
					if(objectMap.get(treeKeyValue)==null)
						treeList.add(object);
				}
			}
			
			for(int i=0;i<treeList.size();i++){
				Object parentObject = treeList.get(i);
				Object parentPrimaryKeyValue=getObjectKeyValue(parentObject,primaryKey);
				for(Object object:list){
					Object treeKeyValue=getObjectKeyValue(object,treeKey);
					if(treeKeyValue.equals(parentPrimaryKeyValue)){
						treeList.add(object);
					}
				}
			}
		}
		return treeList;
	}
	
	
	
	static class TreeObject{
		public Object id;
		public Object parent;
		public String text;
		public Boolean leaf;
		public List<TreeObject> children=null;
	}
	public static List TreeList(List<Object> list,String primaryKey,String textKey,String parentKey){
		Map<Object,TreeObject> mapping = new HashMap();
		for(Object object:list){
			TreeObject treeObject = new TreeObject();
			treeObject.id = getObjectKeyValue(object,primaryKey);
			treeObject.parent = getObjectKeyValue(object,parentKey);
			treeObject.text = "" + getObjectKeyValue(object,textKey);
			mapping.put(treeObject.id, treeObject);
		}
		for(TreeObject treeObject:mapping.values()){
			TreeObject parentObject = mapping.get(treeObject.parent);
			if(parentObject!=null){
				parentObject.leaf=true;
				if(parentObject.children==null)
					parentObject.children=new ArrayList();
				parentObject.children.add(treeObject);
			}
		}
		List treeList = new ArrayList();
		for(TreeObject treeObject:mapping.values()){
			TreeObject parentObject = mapping.get(treeObject.parent);
			if(parentObject==null)
				treeList.add(treeObject);
		}
		return treeList;
	}
	public static String TreeJson(List<Object> list,String primaryKey,String textKey,String parentKey){
		return JSON.toJSONString(Tree.TreeList(list, primaryKey, textKey, parentKey));
	}
	
	private static Object getObjectKeyValue(Object object,String key)
	{
		if(object instanceof Map)
			return ((Map)object).get(key);
		else{
			Field[] fields = object.getClass().getDeclaredFields();
			for(Field field:fields)
			{
				if(field.getName().equals(key)){
					Object value=null;
					try{
						value = field.get(object);
					} catch (Exception e){}
					if(value!=null)
						return value;
				}
			}
			String getMethodName="get"+ForMat(key);
			Method method=null;
			try{
				method = object.getClass().getMethod(getMethodName);
			} catch (Exception e){}
			if(method!=null)
			{
				Object value=null;
				try{
					value=method.invoke(object);
				} catch (Exception e){}
				return value;
			}
		}
		return null;
	}
	private static String ForMat(String string)
	{
		if(string==null || string.equals(""))
			return string;
		return string.substring(0,1).toUpperCase() + string.substring(1);
	}	
}